package com.miplus.ccrm.sms.aicall;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.EnumRCode;
import com.miplus.ccrm.common.ServiceException;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * @Author： Yaohui
 * @Date： 2025/4/28 10:26
 * @Describe：
 */
public class AiCallAESUtil {
    private static Logger logger = LoggerFactory.getLogger(AiCallAESUtil.class);


    private static final String ALGORITHM = "AES";
    private static final String ENCODING = "utf-8";
    private final static String AES_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding";


    // HmacSHA1   AES

    /**
     * AES 加密操作
     *
     * @param content 待加密内容
     * @param key     加密密码
     * @return 返回Base64转码后的加密数据
     */
    public static CmdResVo cbcEncrypt(String content, String key, String iv) {
        byte[] data = null;
        try {
            logger.info("cbcEncrypt:iv={}",iv);
            byte[] contentBytes = content.getBytes(ENCODING);
            data = encryptOrDecrypt(Cipher.ENCRYPT_MODE, contentBytes, key, iv, AES_CBC_PKCS5Padding);
            return new CmdResVo(EnumRCode.Success.value, Base64.encodeBase64String(data));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new CmdResVo(-1,e.getMessage());
        }
    }

    /**
     * AES 解密操作
     */
    public static CmdResVo cbcDecrypt(String content, String key, String iv) {
        try {
            logger.info("cbcDecrypt:iv={}",iv);
            byte[] contentBytes = Base64.decodeBase64(content);
            byte[] data = encryptOrDecrypt(Cipher.DECRYPT_MODE, contentBytes, key, iv, AES_CBC_PKCS5Padding);
            return new CmdResVo(EnumRCode.Success.value,new String(data, ENCODING));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new CmdResVo(-1,e.getMessage());
        }
    }


    /**
     * 根据时间戳13位，生成aes cbc 加密向量 vi
     * 生成规则先把时间戳反向，用零补足16位
     */
    public static String genTimestampIV(String timestamp) {
        String reverse = new StringBuffer(timestamp).reverse().toString();
        return reverse + "000";
    }


    private static byte[] encryptOrDecrypt(int mode, byte[] contentBytes, String key, String iv,
                                           String modeAndPadding) throws Exception {
        byte[] keyBytes = key.getBytes(ENCODING);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        Cipher cipher = Cipher.getInstance(modeAndPadding);// 创建密码器
        if (null != iv) {
            //指定一个初始化向量 (Initialization vector，IV)， IV 必须是16位
            byte[] ivBytes = iv.getBytes(ENCODING);
            cipher.init(mode, keySpec, new IvParameterSpec(ivBytes));
        } else {
            cipher.init(mode, keySpec);
        }
        return cipher.doFinal(contentBytes);
    }


    public static String getSign(String appkey,String appSecret,String timestamp){
        String sign="";
        if(StringUtils.isBlank(appkey)||StringUtils.isBlank(appSecret)||StringUtils.isBlank(timestamp)){
            return sign;
        }

        sign=hmacSha1(appkey+timestamp,appSecret);
        return sign;
    }

    public static String hmacSha1(String daata,String key){
        String result="";
        if(StringUtils.isBlank(daata)||StringUtils.isBlank(key)){
            return result;
        }
        try {
            SecretKeySpec signingKey=new SecretKeySpec(key.getBytes(),"HmacSHA1");
            Mac mac=Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(daata.getBytes());
            result=(new BASE64Encoder()).encode(rawHmac);
        } catch (Exception e) {
            throw new ServiceException(EnumRCode.ApiCryErr.value, EnumRCode.ApiCryErr.name+":"+e.getMessage());

        }
        return result;
    }

}
